//
//  PreferenceController.m
//  ChimooTimer
//
//  Created by Ryan on Thu Sep 25 2003.
//  Chimoosoft (c) 2003-2007 Chimoosoft. All rights reserved.
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.

#import "PreferenceController.h"
#import "CMSCommon.h"
#import "CMSSpeech.h"

@implementation PreferenceController

- (id)init {
	if (self = [super initWithWindowNibName:@"Preferences"]) {
		[self setWindowFrameAutosaveName:@"PrefWindow"];
		defaults = [[NSUserDefaults standardUserDefaults] retain];
		
		voiceIdentifiers = [[NSSpeechSynthesizer availableVoices] retain];
		NSMutableArray * list = [NSMutableArray arrayWithCapacity:20];
		NSEnumerator * e = [voiceIdentifiers objectEnumerator];
		id voice;
		while (voice = [e nextObject]) {
			NSDictionary * dict = [NSSpeechSynthesizer attributesForVoice:voice];
			[list addObject:[dict valueForKey:NSVoiceName]];
		}

		[self willChangeValueForKey:@"availableVoices"];
		availableVoices = [list retain];
		[self didChangeValueForKey:@"availableVoices"];

		[self checkForDockIcon];
	}
	return self;
}

- (void)setMainController:(id)cont {
	mainController = cont;	
}

- (void)checkForDockIcon {
	// This is important to prevent users from doing "bad" things if we're in dockless mode
	// and they toggle the default to go back to dockfull.  It shouldn't let them do dockfull
	// things until the next launch.
	
	NSString * bundlePath = [[NSBundle mainBundle] bundlePath];
	NSURL * url = [NSURL fileURLWithPath: [NSString stringWithFormat: @"%@%@", bundlePath, @"/Contents/Info.plist"]];
	
	id man = [NSFileManager defaultManager];
	
	NSDictionary * plist = [[NSDictionary alloc] initWithContentsOfFile:[url path]];
	BOOL isHidden = ([[plist objectForKey:@"NSUIElement"] isEqualToString:@"1"]);
	
	[defaults setBool:isHidden forKey:@"dockIconIsCurrentlyHidden"];
		
	if (isHidden) {
		[defaults setBool:YES forKey:@"showMenuExtra"];
		[defaults setBool:NO forKey:@"showMainWindow"];
		[defaults setBool:NO forKey:@"showMiniWindow"];
		[defaults setBool:NO forKey:@"showMultiplierWindow"];
	}
	
	[defaults setBool:isHidden forKey:@"hideDockIcon"];	
}


- (IBAction)updateApplicationVisibilityInPlist:(id)sender {
	BOOL hide = [defaults boolForKey:@"hideDockIcon"];
	
	NSString * bundlePath = [[NSBundle mainBundle] bundlePath];
	NSURL * url = [NSURL fileURLWithPath: [NSString stringWithFormat: @"%@%@", bundlePath, @"/Contents/Info.plist"]];
	
	id man = [NSFileManager defaultManager];
	
	NSMutableDictionary * plist = [[NSMutableDictionary alloc] initWithContentsOfFile:[url path]];
	
	if (hide) [plist setObject:@"1" forKey:@"NSUIElement"];
	else [plist setObject:@"0" forKey:@"NSUIElement"];
	
	BOOL b = [plist writeToFile:[url path] atomically:YES];
	
	// Must tell LaunchServices to update otherwise the user has to manually move the app.
	
	NSTask * task = [[NSTask alloc] init];
	[task setLaunchPath:@"/System/Library/Frameworks/ApplicationServices.framework/Frameworks/LaunchServices.framework/Support/lsregister"];
	[task setArguments:[NSArray arrayWithObjects:@"-f", bundlePath, nil]];
	[task launch];
	[task release];
}



- (IBAction)speechRateAdjusted:(id)sender {
	CMSSpeech * speech = [CMSSpeech sharedInstance];
	[speech setRate: [defaults floatForKey:@"speechRate"]];
	
	[[CMSSpeech sharedInstance] stopSpeakingAndSpeakString:
		[NSString stringWithFormat:@"%i words per minute.", (int)floor([defaults floatForKey:@"speechRate"]) ]];
}


- (IBAction)voiceChanged:(id)sender {
	int i = [sender indexOfSelectedItem];
	NSString * ident = [[NSSpeechSynthesizer availableVoices] objectAtIndex:i];
	[defaults setObject:ident forKey:@"defaultVoiceIdentifier"];
	
	CMSSpeech * speech = [CMSSpeech sharedInstance];
	[speech setVoiceWithIdentifier:ident];
	
	[[CMSSpeech sharedInstance] stopSpeakingAndSpeakString:
		[NSString stringWithFormat:@"My name is %@.", [defaults objectForKey:@"defaultVoice"] ]];
	
}

- (void)awakeFromNib {
	
	/*
	// setup and add the toolbars
	toolbar = [[NSToolbar alloc] initWithIdentifier:@"PreferencesToolbar"];
	[toolbar setDelegate:self];
	[toolbar setDisplayMode: NSToolbarDisplayModeIconAndLabel];
	[toolbar setAllowsUserCustomization:NO];
	[toolbar setAutosavesConfiguration:NO];	
	
	[[self window] setToolbar:toolbar];
	*/
}


// sets only if not already set
- (void)setDefaultBool:(BOOL)b forKey:(NSString*)key {
	if ([defaults objectForKey:key]) return;
	[defaults setBool:b forKey:key];
}

// sets only if not already set
- (void)setDefaultFloat:(float)f forKey:(NSString*)key {
	if ([defaults objectForKey:key]) return;
	[defaults setFloat:f forKey:key];
}

// sets only if not already set
- (void)setDefaultInteger:(int)i forKey:(NSString*)key {
	if ([defaults objectForKey:key]) return;
	[defaults setInteger:i forKey:key];
}

// sets only if not already set
- (void)setDefaultObject:(id)o forKey:(NSString*)key {
	if ([defaults objectForKey:key]) return;	
	if (nil == o) return;
	[defaults setObject:o forKey:key];
}


- (void)setupDefaults {	
	if (nil == defaults) defaults = [NSUserDefaults standardUserDefaults];
	
	if (![defaults objectForKey:@"version"] || ([[defaults objectForKey:@"version"] compare:@"1.4.1"] == NSOrderedAscending)) {	
		// prefs are too old, so reset them.
		NSDictionary * dict = [[defaults dictionaryRepresentation] copy];
		NSEnumerator * e = [dict keyEnumerator];
		id obj;
		while (obj = [e nextObject]) {
			[defaults removeObjectForKey:obj];
		}
		[dict release];
	}
		
	[self setDefaultBool:NO forKey:@"displayAlertOnExpire"];
	[self setDefaultObject:@"Your timer has expired." forKey:@"alertText"];
		
	[self setDefaultBool:YES forKey:@"speakAlertOnExpire"];
	[self setDefaultObject:@"com.apple.speech.synthesis.voice.Vicki" forKey:@"defaultVoiceIdentifier"];
	[self setDefaultObject:@"Vicki" forKey:@"defaultVoice"];
	[self setDefaultInteger:220 forKey:@"speechRate"];
	[self setDefaultBool:YES forKey:@"bounceIconOnExpire"];
	[self setDefaultBool:YES forKey:@"BringForwardOnExpire"];

	[self setDefaultBool:YES forKey:@"playSoundOnExpire"];
	[self setDefaultObject:@"Pop" forKey:@"alertSoundName"];
	[self setDefaultInteger:3 forKey:@"numberAlertBeeps"];
	
	[self setDefaultBool:NO forKey:@"launchProgramOnExpire"];

	[self setDefaultBool:NO forKey:@"autoRepeatCountdown"];
	[self setDefaultFloat:30.0 forKey:@"autoRepeatDelay"];
	[self setDefaultObject:@"seconds" forKey:@"autoRepeatDelayUnit"];

	[self setDefaultBool:NO forKey:@"warnBeforeExpire"];
	[self setDefaultFloat:1.0 forKey:@"warnBeforeExpireTime"];
	[self setDefaultObject:@"minutes" forKey:@"warnBeforeExpireUnit"];

	[self setDefaultBool:NO forKey:@"speakTimeOnInterval"];
	[self setDefaultInteger:10 forKey:@"speakTimeInterval"];
	[self setDefaultObject:@"seconds" forKey:@"speakTimeIntervalUnit"];	
	
	[self setDefaultBool:YES forKey:@"showProgressBarForCountdown"];
	
#if defined(__BIG_ENDIAN__)
		// PPC
	[self setDefaultBool:YES forKey:@"pauseMusicOnExpire"];
#elif defined(__LITTLE_ENDIAN__)
		// Intel
	[self setDefaultBool:NO forKey:@"pauseMusicOnExpire"];
#else
#error Do not know the endianess of this architecture
#endif
	
	[self setDefaultBool:NO forKey:@"hideDockIcon"];
	
	[self setDefaultObject:@"Baskerville-SemiBold" forKey:@"defaultFont"];
	[self setDefaultFloat:76.0 forKey:@"defaultFontSize"];
		
	[self setDefaultBool:YES forKey:@"speakTimeOnInterval"];
	[self setDefaultFloat:10.0 forKey:@"speakTimeInterval"];
	[self setDefaultBool:NO forKey:@"speakSeconds"];
	
	[self setDefaultBool:YES forKey:@"speakLastTen"];
	[self setDefaultBool:NO forKey:@"enableSecondTickSound"];
	[self setDefaultObject:@"Pop" forKey:@"secondTickSoundName"];
	[self setDefaultBool:YES forKey:@"enableMinuteTickSound"];
	[self setDefaultObject:@"Purr" forKey:@"minuteTickSoundName"];
	[self setDefaultBool:YES forKey:@"enableHourTickSound"];
	[self setDefaultObject:@"Submarine" forKey:@"hourTickSoundName"];
	
	[self setDefaultBool:YES forKey:@"showMainWindow"];
	[self setDefaultBool:NO forKey:@"showMiniWindow"];
	[self setDefaultBool:NO forKey:@"showMultiplierWindow"];
	[self setDefaultFloat:15.0 forKey:@"multiplierFactor"];
	[self setDefaultBool:YES forKey:@"showMenuExtra"];
	[self setDefaultBool:NO forKey:@"showInDockIcon"];
	
	[self setDefaultObject:@"HH:MM:SS" forKey:@"mainFormat"];
	[self setDefaultBool:YES forKey:@"showSecondFractions"];
	
	[self setDefaultFloat:0.1 forKey:@"foregroundRefreshRate"];
	[self setDefaultFloat:1.0 forKey:@"backgroundRefreshRate"];
	
	[self setDefaultBool:YES forKey:@"checkForNewVersionsAutomatically"];
	
	[self setDefaultBool:NO forKey:@"enableSpeechRecognition"];
	[self setDefaultBool:YES forKey:@"showDisclaimer"];
	[self setDefaultBool:NO forKey:@"warnOnStop"];
	
	[self setDefaultBool:YES forKey:@"countDownAtLastLaunch"];
	
	[self setDefaultInteger:0 forKey:@"hMenuSetting"];
	[self setDefaultInteger:0 forKey:@"mMenuSetting"];
	[self setDefaultInteger:10 forKey:@"sMenuSetting"];
	
}


- (IBAction)doNothing:(id)sender {
	[tabView selectTabViewItemWithIdentifier:@"advanced"];
}

// sets the action, picture, and label for each toolbar item
- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar 
	 itemForItemIdentifier:(NSString*)itemIdentifier 
 willBeInsertedIntoToolbar:(BOOL)flag {
	
	NSToolbarItem * item;
	item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
	
	if ([itemIdentifier isEqualToString:@"StartStopButton"]) {
		[item setLabel:NSLocalizedString(@"Start/Stop", nil)];
		[item setPaletteLabel:NSLocalizedString(@"Start/Stop", nil)];
		[item setToolTip:NSLocalizedString(@"Start/Stop Timer", nil)];
		[item setAction:@selector(doNothing:)];
		[item setImage:[NSImage imageNamed:@"Start"]];
	} else if ([itemIdentifier isEqualToString:@"ResetButton"]) {
		[item setLabel:NSLocalizedString(@"Reset", @"")];
		[item setPaletteLabel:NSLocalizedString(@"Reset", @"")];	
		[item setImage:[NSImage imageNamed:@"Reset"]];
		[item setAction:@selector(doNothing:)];
	}
	
	[item autorelease];	
	return item;
}


// returns an array of all allowable toolbar item identifiers
- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar {
	
	NSArray * array;
	
	array = [NSArray arrayWithObjects:
		NSToolbarSeparatorItemIdentifier,
		NSToolbarSpaceItemIdentifier,
		NSToolbarFlexibleSpaceItemIdentifier,
		@"StartStopButton",
		@"ResetButton", nil];
	
	return array;
}

// Returns an array representing the default set of toolbar identifiers.
- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar {
	NSArray * array = nil;
	
	array = [NSArray arrayWithObjects:
		@"StartStopButton",
		@"ResetButton", nil];
	
	return array;
}

- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem {
	return YES;
}


- (IBAction)playMenuSound:(id)sender {
	NSSound * sound = [NSSound soundNamed: [sender title]];
	if (sound != nil) [sound play];
	
	[mainController updateSounds];
}


- (IBAction)browseForFile:(id)sender {
	NSOpenPanel * openPanel = [NSOpenPanel openPanel];
	[openPanel setCanChooseFiles:YES];
	[openPanel setCanChooseDirectories:NO];
	[openPanel setResolvesAliases:NO];
	[openPanel setAllowsMultipleSelection:NO];
	
	[openPanel runModalForDirectory:nil file:nil types:nil];
	
	NSArray * fileNames = [openPanel filenames];

	if ([fileNames count] <= 0) return;
	
	NSMutableString * path = [fileNames objectAtIndex:0];
	[[NSUserDefaults standardUserDefaults] setObject:path forKey:@"launchProgramPath"];

	NSArray *pathComponents = [path pathComponents];
	[[NSUserDefaults standardUserDefaults] setObject:[pathComponents lastObject] forKey:@"launchProgramName"];
	
}

- (IBAction)openSpeechPreferences:(id)sender {
	NSAppleEventDescriptor * d = [CMSCommon runCompiledAppleScriptInBundle:@"openspeech"];
}




- (void)dealloc {
	[toolbar release];
	[defaults release];
	[availableVoices release];
	[voiceIdentifiers release];
	
	[super dealloc];
}
@end
